package com.lcredu.aop.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

import static com.lcredu.aop.proxy.LcrAOP.after;
import static com.lcredu.aop.proxy.LcrAOP.before;

/**
 * @author 黎长容
 * @date 2025-07-15 12:27
 */
public class SmartAnimalProxy {
    //提供一个动态代理的目标对象,需要实现接口
    private SmartAnimal smartAnimal;

    public SmartAnimalProxy(SmartAnimal smartAnimal) {
        this.smartAnimal = smartAnimal;
    }

//    public void before(String name, Object[] args) {
//        System.out.println("before--前置通知---日志-方法名-" + name + "-参数" + Arrays.asList(args));
//    }
//    
//    public void after(Object result){
//        System.out.println("after--后置通知---方法内部打印 result = " + result);
//    }

    public SmartAnimal getSmartAnimalProxy() {
        ClassLoader classLoader = smartAnimal.getClass().getClassLoader();
        Class<?>[] interfaces = smartAnimal.getClass().getInterfaces();
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String name = method.getName();
                Object result = null;
                try {
                    before(name, args);
                    result = method.invoke(smartAnimal, args);
                    after(result);
                } catch (IllegalAccessException e) {
                    System.out.println(e.getMessage());
                    System.out.println("异常通知---finally输出--日志-方法名-" + name + "-异常类型=" + e.getClass().getName());
                } finally {
                    System.out.println("最终通知---finally输出--日志-方法名-" + name + "-结果 result=" + result);
                }

                return result;
            }
        };

        SmartAnimal smartAnimal = (SmartAnimal) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);

        return smartAnimal;
    }
}
